home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / system-tools / dircomp / src / dircmp2.c
C/C++ Source or Header  |  1996-02-26  |  6KB  |  286 lines

  1. /*
  2.     dircmp2 command
  3.     alpha version 7 & beta version 1, derived from alpha version 6
  4.     revision: 4.11.1995
  5.     (C) 1995 Thomas Radtke
  6.     E-Mail: Thomas.Radtke@rz.uni-osnabrueck.de
  7.     covered by the GPL, see COPYING for details
  8. */
  9.  
  10. #include <sys/types.h>
  11. #include <dirent.h>
  12. #include <stdio.h>
  13. #include <sys/stat.h>
  14. #include <fcntl.h>
  15.  
  16. #define MAXENTRY 1000
  17. #define TABSIZE 2
  18.  
  19. int tab,rec,inv,cmp,dirs,fls,pathpart,help;
  20. int tabulator=0;
  21.  
  22. int main(int argc, char **argv)
  23. {
  24.     int cnt;
  25.     void dircmp2();
  26.  
  27.     rec=0;
  28.     inv=0;
  29.     cmp=0;
  30.     dirs=0;
  31.     fls=0;
  32.     pathpart=0;
  33.     help=0;
  34.     tab=0;
  35.  
  36.     cnt=0;
  37.     if (argc>1)
  38.     {
  39.         while (argv[++cnt][0]=='-' && cnt<argc)
  40.         {
  41.             switch(argv[cnt][1])
  42.             {
  43.                 case 't':
  44.                     tab=1;
  45.                     break;
  46.                 case 'h':
  47.                     help=1;
  48.                     break;
  49.                 case 'p':
  50.                     pathpart=1;
  51.                     break;
  52.                 case 'f':
  53.                     fls=1;
  54.                     dirs=0;
  55.                     break;
  56.                 case 'i':
  57.                     inv=1;
  58.                     break;
  59.                 case 'd':
  60.                     dirs=1;
  61.                     fls=0;
  62.                     break;
  63.                 case 'c':
  64.                     cmp=1;
  65.                     break;
  66.                 case 'r':
  67.                     rec=1;
  68.                     break;
  69.                 default:
  70.                     fprintf(stderr,"%s: unknown option -%c\n",argv[0],argv[cnt][1]);
  71.                     exit(20);
  72.                     break;
  73.             }
  74.         }
  75.         argc-=(cnt-1);
  76.     }
  77.     if (argc<2 || help)
  78.     {
  79.         fprintf(stderr,"usage: %s [-{cdfhiprt}] directory1 [directory2]\n",*argv);
  80.         if (help)
  81.         {
  82.             fprintf(stderr,"\nThe %s command lists all files and directories of directory1, that\n",*argv);
  83.             fprintf(stderr,"cannot be found in directory2. If directory2 is omitted, '.' is used\n\nFlags:\n\n");
  84.             fprintf(stderr,"-c  compare files\n");
  85.             fprintf(stderr,"-d  show only directorys\n");
  86.             fprintf(stderr,"-f  show only files\n");
  87.             fprintf(stderr,"-h  this page\n");
  88.             fprintf(stderr,"-i  inverse comparison\n");
  89.             fprintf(stderr,"-p  show full pathnames\n");
  90.             fprintf(stderr,"-r  subdir scan\n");
  91.             fprintf(stderr,"-t  indent subdir results\n");
  92.             exit(0);
  93.         }
  94.         else {
  95.             fprintf(stderr,"use option -h to show the help page\n");
  96.             exit(20);
  97.         }
  98.     }
  99.  
  100.     if (argc==3)
  101.         dircmp2(*argv,argv[cnt],argv[cnt+1]);
  102.     else
  103.         dircmp2(*argv,argv[cnt],(char *)".");
  104.     exit(0);
  105. }
  106.  
  107. void dircmp2(char *argv, char *argv1, char *argv2)
  108. {
  109.     DIR *dir1,*dir2;
  110.     struct dirent *entry;
  111.     int d1,d2,s1,s2,equal,ind1,ind2,i,j,k;
  112.     struct stat fileinfo,fileinfo2;
  113.     char *buf,*buf2,*buffer1,*buffer2;
  114.     int fh;
  115.     char **dir_name_list_1,**dir_name_list_2;
  116.     void tabul();
  117.  
  118.     if (!(dir_name_list_1=(char **)malloc(MAXENTRY*sizeof(char *))))
  119.     {
  120.         printf("%s: memory exhausted\n",argv);
  121.         exit(20);
  122.     }
  123.     if (!(dir_name_list_2=(char **)malloc(MAXENTRY*sizeof(char *))))
  124.     {
  125.         printf("%s: memory exhausted\n",argv);
  126.         exit(20);
  127.     }
  128.     if (!(dir1=(DIR *)opendir((char *)argv1)))
  129.     {
  130.         fprintf(stderr,"%s: nonexistant directory %s\n",argv,argv1);
  131.         exit(20);
  132.     }
  133.     if (!(dir2=(DIR *)opendir((char *)argv2)))
  134.     {
  135.         fprintf(stderr,"%s: nonexistant directory %s\n",argv,argv2);
  136.         closedir(dir1);
  137.         exit(20);
  138.     }
  139.  
  140.     ind1=0;
  141.     ind2=0;
  142.  
  143.     while ((entry=(struct dirent *)readdir(dir1)))
  144.     {
  145.         if (!strcmp(".",entry->d_name) || !strcmp("..",entry->d_name)) continue;
  146.         if (!(dir_name_list_1[ind1]=(char *)malloc(entry->d_namlen+1))) {
  147.             printf("%s: memory exhausted\n",argv);
  148.             closedir(dir1);
  149.             closedir(dir2);
  150.             exit(20);
  151.         }
  152.         strcpy(dir_name_list_1[ind1],entry->d_name);
  153.         if (ind1++==MAXENTRY)
  154.         {
  155.             printf("%s: too much entries\n",argv);
  156.             closedir(dir1);
  157.             closedir(dir2);
  158.             exit(20);
  159.         }
  160.     }
  161.     while ((entry=(struct dirent *)readdir(dir2)))
  162.     {
  163.         if (!strcmp(".",entry->d_name) || !strcmp("..",entry->d_name)) continue;
  164.         if (!(dir_name_list_2[ind2]=(char *)malloc(entry->d_namlen+1))) {
  165.             printf("%s: memory exhausted\n",argv);
  166.             closedir(dir1);
  167.             closedir(dir2);
  168.             exit(20);
  169.         }
  170.         strcpy(dir_name_list_2[ind2],entry->d_name);
  171.         if (ind2++==MAXENTRY)
  172.         {
  173.             printf("%s: too much entries\n",argv);
  174.             closedir(dir1);
  175.             closedir(dir2);
  176.             exit(20);
  177.         }
  178.     }
  179.  
  180.     for (i=0; i<ind1; i++) {
  181.         equal=0;
  182.         for (j=0; j<ind2; j++) {
  183.             if (!strcmp(dir_name_list_1[i],dir_name_list_2[j])) {
  184.                 equal=1;
  185.                 break;
  186.             }
  187.         }
  188.         if ((inv && equal) || (!inv && !equal) || (!inv && equal && (cmp || rec))) {
  189.             if (!(buf=(char *)malloc(strlen(dir_name_list_1[i])+strlen(argv1)+2))) {
  190.                 printf("%s: memory exhausted\n",argv);
  191.                 closedir(dir1);
  192.                 closedir(dir2);
  193.                 exit(20);
  194.             }
  195.             *buf=(char)0;
  196.             strcpy(buf,argv1);
  197.             strcat(buf,"/");
  198.             strcat(buf,dir_name_list_1[i]);
  199.             stat(buf,&fileinfo);
  200.             d1=S_ISDIR(fileinfo.st_mode);
  201.             if (equal) {
  202.                 if (!(buf2=(char *)malloc(strlen(dir_name_list_2[j])+strlen(argv2)+2))) {
  203.                     printf("%s: memory exhausted\n",argv);
  204.                     closedir(dir1);
  205.                     closedir(dir2);
  206.                     exit(20);
  207.                 }
  208.                 *buf2=(char)0;
  209.                 strcpy(buf2,argv2);
  210.                 strcat(buf2,"/");
  211.                 strcat(buf2,dir_name_list_2[j]);
  212.                 stat(buf2,&fileinfo2);
  213.                 d2=S_ISDIR(fileinfo2.st_mode);
  214.                 if (d1!=d2) equal=0;
  215.                 else if (cmp && fileinfo.st_size!=fileinfo2.st_size) equal=0;
  216.                 else if (!d1 && cmp) {
  217.                     buffer1=(char *)malloc(fileinfo.st_size+1);
  218.                     buffer2=(char *)malloc(fileinfo.st_size+1);
  219.                     if (!buffer1 || !buffer2) {
  220.                         fprintf(stderr,"%s: warning: memory exhausted\n",argv);
  221.                         fprintf(stderr,"the files %s and %s are considered to be different\n",buf,buf2);
  222.                         if (buffer1) free(buffer1);
  223.                         if (buffer2) free(buffer2);
  224.                         equal=0;
  225.                     }
  226.                     else {
  227.                         fh=open(buf,O_RDONLY,0);
  228.                         s1=read(fh,buffer1,fileinfo.st_size);
  229.                         close(fh);
  230.                         fh=open(buf2,O_RDONLY,0);
  231.                         s2=read(fh,buffer2,fileinfo.st_size);
  232.                         close(fh);
  233.                         if (s1!=fileinfo.st_size) {
  234.                             printf("%s: error reading file %s\n",argv,buf);
  235.                             closedir(dir1);
  236.                             closedir(dir2);
  237.                             exit(20);
  238.                         }
  239.                         if (s2!=fileinfo.st_size) {
  240.                             printf("%s: error reading file %s\n",argv,buf2);
  241.                             closedir(dir1);
  242.                             closedir(dir2);
  243.                             exit(20);
  244.                         }
  245.                         for (k=0; k<fileinfo.st_size; k++) {
  246.                             if (buffer1[k]!=buffer2[k]) break;
  247.                         }
  248.                         free(buffer1);
  249.                         free(buffer2);
  250.                         if (k!=fileinfo.st_size) equal=0;
  251.                     }
  252.                 }
  253.             }
  254.             if (rec && equal && d1) {
  255.                 tabulator+=TABSIZE;
  256.                 dircmp2(argv,buf,buf2);
  257.                 tabulator-=TABSIZE;
  258.             }
  259.             else if ((inv && equal) || (!inv && !equal)) {
  260.                 if ((d1 && dirs) || (!d1 && fls) || (!dirs && !fls)) {
  261.                     if (!pathpart) {
  262.                         if (tab) tabul();
  263.                         printf("%s\n",dir_name_list_1[i]);
  264.                     }
  265.                     else {
  266.                         if (tab) tabul();
  267.                         printf("%s\n",buf);
  268.                     }
  269.                 }
  270.             }
  271.         }
  272.     }
  273.     closedir(dir1);
  274.     closedir(dir2);
  275.     free(dir_name_list_1);
  276.     free(dir_name_list_2);
  277.     return;
  278. }
  279.  
  280. void tabul()
  281. {
  282.     int i;
  283.  
  284.     for (i=0; i<tabulator; i++) printf(" ");
  285. }
  286.